package com.cuixichang.minimalism.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cuixichang.minimalism.acl.RelevanceDesign;
import com.cuixichang.minimalism.basal.base.Result;
import com.cuixichang.minimalism.basal.enums.IsEnableEnum;
import com.cuixichang.minimalism.basal.enums.ResponseCoderEnum;
import com.cuixichang.minimalism.core.security.userdetails.CredentialDetail;
import com.cuixichang.minimalism.core.security.utils.SecurityBeanUtil;
import com.cuixichang.minimalism.domain.IRoleCommandService;
import com.cuixichang.minimalism.transfer.dto.IRoleDTO;
import com.cuixichang.minimalism.transfer.factory.IRoleAssembler;
import com.cuixichang.minimalism.transfer.page.IRolePageRequest;
import com.cuixichang.minimalism.transfer.page.IRoleRequest;
import com.cuixichang.minimalism.transfer.vo.IRoleVO;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import com.cuixichang.minimalism.service.IRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 角色信息管理表表控制层
 *
 * @author cuixichang
 * @date 2024-11-23
 */
@Api(tags = "角色信息管理表对象功能接口")
@RestController
@RequestMapping("role")
@RequiredArgsConstructor
public class IRoleController {
    @Autowired
    private IRoleService iRoleService;
    @Autowired
    private IRoleCommandService iRoleCommandService;
    @Autowired
    private RelevanceDesign relevanceDesign;
    @PostMapping("/info")
    @ApiOperation(value = "创建角色基本信息")
    public Result<IRoleVO> insert(@RequestBody IRoleRequest request) {
        IRoleDTO roleDTO = IRoleAssembler.INSTANCT.convertDto(request);
        IRoleDTO insert = iRoleCommandService.insert(roleDTO,SecurityBeanUtil.getCredentialDetail());
        return Result.ok("角色信息创建成功", IRoleAssembler.INSTANCT.convertVo(insert));
    }

    @GetMapping("/info/{systemCode}/{id}")
    @ApiOperation(value = "查询角色基本信息通过ID")
    public Result<IRoleVO> selectById(@PathVariable("id") Long id, @PathVariable("systemCode") String systemCode){
        CredentialDetail credentialDetail = SecurityBeanUtil.getCredentialDetail();
        IRoleDTO role = iRoleCommandService.selectByIdHasPreCheck(id, systemCode, credentialDetail);
        return Result.ok("查询角色信息完成", IRoleAssembler.INSTANCT.convertVo(role));
    }

    @GetMapping("/infoByCode/{systemCode}/{roleCode}")
    @ApiOperation(value = "查询角色基本信息通过RoleCode")
    public Result<IRoleVO> selectByCode(@PathVariable String roleCode, @PathVariable("systemCode") String systemCode){
        CredentialDetail credentialDetail = SecurityBeanUtil.getCredentialDetail();
        IRoleDTO role = iRoleCommandService.selectByCodeHasPreCheck(roleCode, systemCode, credentialDetail);
        return Result.ok("查询角色信息完成", IRoleAssembler.INSTANCT.convertVo(role));
    }

    @DeleteMapping("/info/{systemCode}/{id}")
    @ApiOperation(value = "删除角色基本信息通过ID")
    public Result deleteById(@PathVariable Long id,@PathVariable("systemCode") String systemCode){
        CredentialDetail credentialDetail = SecurityBeanUtil.getCredentialDetail();
        boolean deleteFlag = iRoleCommandService.deleteByIdHasPreCheck(id, systemCode,credentialDetail);
        return deleteFlag?Result.ok(ResponseCoderEnum.Success.getDesc(), true):
                Result.error(ResponseCoderEnum.Failed.getCode(), "删除失败");
    }

    @PutMapping("/info/{systemCode}/{id}")
    @ApiOperation(value = "修改角色基本信息通过ID")
    public Result updateById(@PathVariable Long id,@PathVariable("systemCode") String systemCode, @RequestBody IRoleRequest roleRequest){
        IRoleDTO roleDTO = IRoleAssembler.INSTANCT.convertDto(roleRequest);
        roleDTO.setId(id);
        roleDTO.setCreateSystemCode(systemCode);
        boolean update = iRoleCommandService.updateByIdHasPreCheck(roleDTO,SecurityBeanUtil.getCredentialDetail());
        return update?Result.ok(ResponseCoderEnum.Success.getDesc(), true):
                Result.error(ResponseCoderEnum.Failed.getCode(), "修改失败");
    }

    @GetMapping("/page")
    @ApiOperation(value = "分页条件查询用户可操作角色信息")
    public Result<Page<IRoleVO>> selectPageByConditional(IRolePageRequest request){
        IRoleDTO roleDTO = IRoleAssembler.INSTANCT.convertDto(request);
        Page<IRoleDTO> iRolePage = iRoleCommandService.selectPageByConditional(roleDTO, request.getPageNo(), request.getPageSize()
                ,SecurityBeanUtil.getCredentialDetail());
        Page<IRoleVO> result = new Page<>(iRolePage.getCurrent(), iRolePage.getSize(), iRolePage.getTotal());
        result.setRecords(iRolePage.getRecords().stream().map(IRoleAssembler.INSTANCT::convertVo).collect(Collectors.toList()));
        return Result.ok("分页查询用户角色信息完成",result);
    }

    @GetMapping("/login/{bindingStatus}/{loginId}")
    @ApiOperation(value = "账号已绑定/允许绑定角色查询")
    public Result<Page<IRoleVO>> loginBindingRoles(@PathVariable("bindingStatus") String bindingStatus,
                                                   @PathVariable("loginId") Long loginId,
                                                   IRolePageRequest request) {
        IRoleDTO roleDTO = IRoleAssembler.INSTANCT.convertDto(request);
        CredentialDetail credentialDetail = SecurityBeanUtil.getCredentialDetail();
        Page<IRoleDTO> iRolePage = Optional.ofNullable(bindingStatus).filter(code -> IsEnableEnum.YES.getCode().toString().equals(code)).map(
                code -> iRoleCommandService.loginHasBindingRoles(roleDTO, request.getPageNo(), request.getPageSize(), loginId, credentialDetail)
        ).orElseGet(() -> iRoleCommandService.loginUnBindingRoles(roleDTO, request.getPageNo(), request.getPageSize(), loginId, credentialDetail));
        List<IRoleDTO> records = iRolePage.getRecords();
        Page<IRoleVO> result = new Page(iRolePage.getCurrent(),iRolePage.getSize(),iRolePage.getTotal());
        result.setRecords(records.stream().map(IRoleAssembler.INSTANCT::convertVo).collect(Collectors.toList()));
        return Result.ok("查询成功",result);
    }

    @GetMapping("/menu/{bindingStatus}/{menuId}")
    @ApiOperation(value = "菜单已绑定/允许绑定角色查询")
    public Result<Page<IRoleVO>> menuBindingRoles(@PathVariable("bindingStatus") String bindingStatus,
                                                  @PathVariable("menuId") Long menuId,
                                                  IRolePageRequest request) {
        IRoleDTO roleDTO = IRoleAssembler.INSTANCT.convertDto(request);
        CredentialDetail credentialDetail = SecurityBeanUtil.getCredentialDetail();
        Page<IRoleDTO> iRolePage = Optional.ofNullable(bindingStatus).filter(code -> IsEnableEnum.YES.getCode().toString().equals(code)).map(
                code -> iRoleCommandService.menuHasBindingRoles(roleDTO, request.getPageNo(), request.getPageSize(), menuId, credentialDetail)
        ).orElseGet(() -> iRoleCommandService.menuUnBindingRoles(roleDTO, request.getPageNo(), request.getPageSize(), menuId, credentialDetail));
        List<IRoleDTO> records = iRolePage.getRecords();
        Page<IRoleVO> result = new Page(iRolePage.getCurrent(),iRolePage.getSize(),iRolePage.getTotal());
        result.setRecords(records.stream().map(IRoleAssembler.INSTANCT::convertVo).collect(Collectors.toList()));
        return Result.ok("查询成功",result);
    }

    @GetMapping("/permission/{bindingStatus}/{permissionId}")
    @ApiOperation(value = "权限已绑定/允许绑定角色查询")
    public Result<Page<IRoleVO>> permissionBindingRoles(@PathVariable("bindingStatus") String bindingStatus,
                                                        @PathVariable("permissionId") Long permissionId,
                                                        IRolePageRequest request) {
        IRoleDTO roleDTO = IRoleAssembler.INSTANCT.convertDto(request);
        CredentialDetail credentialDetail = SecurityBeanUtil.getCredentialDetail();
        Page<IRoleDTO> iRolePage = Optional.ofNullable(bindingStatus).filter(code -> IsEnableEnum.YES.getCode().toString().equals(code)).map(
                code -> iRoleCommandService.permissionHasBindingRoles(roleDTO, request.getPageNo(), request.getPageSize(), permissionId, credentialDetail)
        ).orElseGet(() -> iRoleCommandService.permissionUnBindingRoles(roleDTO, request.getPageNo(), request.getPageSize(), permissionId, credentialDetail));
        List<IRoleDTO> records = iRolePage.getRecords();
        Page<IRoleVO> result = new Page(iRolePage.getCurrent(),iRolePage.getSize(),iRolePage.getTotal());
        result.setRecords(records.stream().map(IRoleAssembler.INSTANCT::convertVo).collect(Collectors.toList()));
        return Result.ok("查询成功",result);
    }

    @GetMapping("/router/{bindingStatus}/{routerId}")
    @ApiOperation(value = "路由已绑定/允许绑定角色查询")
    public Result<Page<IRoleVO>> routerBindingRoles(@PathVariable("bindingStatus") String bindingStatus,
                                                    @PathVariable("routerId") Long routerId,
                                                    IRolePageRequest request) {
        IRoleDTO roleDTO = IRoleAssembler.INSTANCT.convertDto(request);
        CredentialDetail credentialDetail = SecurityBeanUtil.getCredentialDetail();
        Page<IRoleDTO> iRolePage = Optional.ofNullable(bindingStatus).filter(code -> IsEnableEnum.YES.getCode().toString().equals(code)).map(
                code -> iRoleCommandService.routerHasBindingRoles(roleDTO, request.getPageNo(), request.getPageSize(), routerId, credentialDetail)
        ).orElseGet(() -> iRoleCommandService.routerUnBindingRoles(roleDTO, request.getPageNo(), request.getPageSize(), routerId, credentialDetail));
        List<IRoleDTO> records = iRolePage.getRecords();
        Page<IRoleVO> result = new Page(iRolePage.getCurrent(),iRolePage.getSize(),iRolePage.getTotal());
        result.setRecords(records.stream().map(IRoleAssembler.INSTANCT::convertVo).collect(Collectors.toList()));
        return Result.ok("查询成功",result);
    }

    @PostMapping("/menu/{bindingStatus}/{roleId}/{menuId}")
    @ApiOperation(value = "角色绑定（解绑）菜单")
    public Result<Boolean> menuBindingStatus(@PathVariable("bindingStatus") String bindingStatus,
                                            @PathVariable("roleId") Long roleId,
                                            @PathVariable("menuId") Long menuId){
        return Result.ok("操作成功",iRoleCommandService.menuBindingStatus(roleId, menuId, IsEnableEnum.YES.getCode().toString().equals(bindingStatus),
                SecurityBeanUtil.getCredentialDetail()));
    }

    @PostMapping("/permission/{bindingStatus}/{roleId}/{permissionId}")
    @ApiOperation(value = "权限绑定（解绑）角色")
    public Result<Boolean> permissionBindingStatus(@PathVariable("bindingStatus") String bindingStatus,
                                                   @PathVariable("roleId") Long roleId,
                                                   @PathVariable("permissionId") Long permissionId){
        return Result.ok("操作成功",relevanceDesign.rolePermissionBindingStatus(roleId, permissionId, IsEnableEnum.YES.getCode().toString().equals(bindingStatus),
                SecurityBeanUtil.getCredentialDetail()));
    }

    @PostMapping("/login/{bindingStatus}/{roleId}/{loginId}")
    @ApiOperation(value = "账号绑定（解绑）角色")
    public Result<Boolean> loginBindingStatus(@PathVariable("bindingStatus") String bindingStatus,
                                              @PathVariable("roleId") Long roleId,
                                              @PathVariable("loginId") Long loginId){
        return Result.ok("操作成功",relevanceDesign.roleLoginBindingStatus(roleId, loginId, IsEnableEnum.YES.getCode().toString().equals(bindingStatus),
                SecurityBeanUtil.getCredentialDetail()));
    }

    @PostMapping("/router/{bindingStatus}/{roleId}/{routerId}")
    @ApiOperation(value = "角色绑定（解绑）菜单")
    public Result<Boolean> routerBindingStatus(@PathVariable("bindingStatus") String bindingStatus,
                                               @PathVariable("roleId") Long roleId,
                                               @PathVariable("routerId") Long routerId){
        return Result.ok("操作成功",relevanceDesign.routerBindingStatus(routerId,roleId, true, IsEnableEnum.YES.getCode().toString().equals(bindingStatus),
                SecurityBeanUtil.getCredentialDetail()));
    }
}
